let EventEmitter = require('events');
let fs = require('mz/fs');
class ReadStream extends EventEmitter {
    constructor(path, options) {
        super();
        this.path = path;
        this.flags = options.flags || 'r';
        this.fd = options.fd || null;
        this.encoding = options.encoding || null;
        this.mode = options.mode || 0o666;
        this.autoClose = options.autoClose || 'true';
        this.start = options.start || 0;
        this.end = options.end || null;
        this.highWaterMark = options.highWaterMark || 64 * 1024;
        // 是否是流动模式 默认非流动模式
        this.flowing = false;
        // 用来记录当前读到哪了
        this.position = this.start || 0;
        // 打开文件
        this.open();
        // 用户监听了'data',用流动模式读取文件
        this.on('newListener', (type) => {
            if (type === 'data') {
                this.flowing = true;
                this.read();
            }
        })
    }
    open() {
        fs.open(this.path, this.flags, this.mode).then(fd => {
            this.fd = fd;
            this.emit('open', fd)
        }).catch(err => {
            return this.emit('error', err)
        })
    }
    read() {
        // 监听'data'的时候文件可能还没打开
        if (typeof this.fd !== 'number') {
            return this.once('open', () => this.read())
        }
        // 有end值的情况下，直接用hightWaterMark可能存在多取的情况，得计算一个靠谱的值
        let howMuchToRead = this.end ? Math.min(this.highWaterMark, this.end - this.position) : this.highWaterMark;
        // 开辟多少个内存空位，将读取的内容放到buffer中
        let buffer = Buffer.alloc(howMuchToRead)

        fs.read(this.fd, buffer, 0, howMuchToRead, this.position).then(bytesRead => {
            if (bytesRead[0] > 0) {
                this.position += bytesRead[0];
                let chunk = this.encoding ? buffer.slice(0, bytesRead[0]).toString(this.encoding) : buffer.slice(0, bytesRead[0]);
                this.emit('data', chunk)
                if (this.flowing) {
                    this.read()
                }
            } else {
                this.emit('end')
                this.emit('close')
            }
        })
    }
    pause() {
        this.flowing = false
    }
    resume() {
        this.flowing = true
        this.read()
    }
}


module.exports = ReadStream;